package configs

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/spf13/viper"
)

// Config 应用配置结构体，包含所有配置项
type Config struct {
	Server     ServerConfig     `yaml:"server"`     // 服务器配置
	Database   DatabaseConfig   `yaml:"database"`   // 数据库配置
	Log        LogConfig        `yaml:"log"`        // 日志配置
	Security   SecurityConfig   `yaml:"security"`   // 安全配置
	Monitoring MonitoringConfig `yaml:"monitoring"` // 监控配置
}

// ServerConfig 服务器配置结构体
type ServerConfig struct {
	Port           int    `yaml:"port"`             // 服务器监听端口
	Host           string `yaml:"host"`             // 服务器监听地址
	ReadTimeout    int    `yaml:"read_timeout"`     // 读取超时时间（秒）
	WriteTimeout   int    `yaml:"write_timeout"`    // 写入超时时间（秒）
	MaxHeaderBytes int    `yaml:"max_header_bytes"` // HTTP头部最大字节数
}

// DatabaseConfig 数据库配置结构体
type DatabaseConfig struct {
	Type       string           `yaml:"type"`       // 数据库类型（mysql/postgresql）
	MySQL      MySQLConfig      `yaml:"mysql"`      // MySQL数据库配置
	PostgreSQL PostgreSQLConfig `yaml:"postgresql"` // PostgreSQL数据库配置
}

// MySQLConfig MySQL数据库配置结构体
type MySQLConfig struct {
	Host            string        `yaml:"host"`              // 数据库主机地址
	Port            int           `yaml:"port"`              // 数据库端口
	Username        string        `yaml:"username"`          // 数据库用户名
	Password        string        `yaml:"password"`          // 数据库密码
	DBName          string        `yaml:"dbname"`            // 数据库名称
	MaxIdleConns    int           `yaml:"max_idle_conns"`    // 最大空闲连接数
	MaxOpenConns    int           `yaml:"max_open_conns"`    // 最大打开连接数
	ConnMaxLifetime time.Duration `yaml:"conn_max_lifetime"` // 连接最大生命周期
	Charset         string        `yaml:"charset"`           // 字符集
	Collation       string        `yaml:"collation"`         // 排序规则
	ParseTime       bool          `yaml:"parse_time"`        // 是否解析时间
	Loc             string        `yaml:"loc"`               // 时区设置
}

// PostgreSQLConfig PostgreSQL数据库配置结构体
type PostgreSQLConfig struct {
	Host            string        `yaml:"host"`              // 数据库主机地址
	Port            int           `yaml:"port"`              // 数据库端口
	Username        string        `yaml:"username"`          // 数据库用户名
	Password        string        `yaml:"password"`          // 数据库密码
	DBName          string        `yaml:"dbname"`            // 数据库名称
	SSLMode         string        `yaml:"sslmode"`           // SSL模式
	Timezone        string        `yaml:"timezone"`          // 时区设置
	MaxIdleConns    int           `yaml:"max_idle_conns"`    // 最大空闲连接数
	MaxOpenConns    int           `yaml:"max_open_conns"`    // 最大打开连接数
	ConnMaxLifetime time.Duration `yaml:"conn_max_lifetime"` // 连接最大生命周期
}

// LogConfig 日志配置结构体
type LogConfig struct {
	Level      string `yaml:"level"`       // 日志级别（debug/info/warn/error/fatal）
	Format     string `yaml:"format"`      // 日志格式（json/text）
	Output     string `yaml:"output"`      // 日志输出位置（stdout/file）
	FilePath   string `yaml:"file_path"`   // 日志文件路径
	MaxSize    int    `yaml:"max_size"`    // 单个日志文件最大大小（MB）
	MaxAge     int    `yaml:"max_age"`     // 日志文件保留天数
	MaxBackups int    `yaml:"max_backups"` // 保留的旧日志文件个数
	Compress   bool   `yaml:"compress"`    // 是否压缩旧日志文件
}

// SecurityConfig 安全配置结构体
type SecurityConfig struct {
	JWTSecret string     `yaml:"jwt_secret"` // JWT密钥
	JWTExpire int        `yaml:"jwt_expire"` // JWT过期时间（分钟）
	CORS      CORSConfig `yaml:"cors"`       // CORS跨域配置
}

// CORSConfig CORS跨域配置结构体
type CORSConfig struct {
	AllowedOrigins   []string `yaml:"allowed_origins"`   // 允许的源域名列表
	AllowedMethods   []string `yaml:"allowed_methods"`   // 允许的HTTP方法列表
	AllowedHeaders   []string `yaml:"allowed_headers"`   // 允许的HTTP头部列表
	ExposedHeaders   []string `yaml:"exposed_headers"`   // 暴露的HTTP头部列表
	AllowCredentials bool     `yaml:"allow_credentials"` // 是否允许发送认证信息
	MaxAge           int      `yaml:"max_age"`           // 预检请求结果缓存时间（秒）
}

// MonitoringConfig 监控配置结构体
type MonitoringConfig struct {
	Enabled     bool              `yaml:"enabled"`      // 是否启用监控
	Prometheus  PrometheusConfig  `yaml:"prometheus"`   // Prometheus监控配置
	HealthCheck HealthCheckConfig `yaml:"health_check"` // 健康检查配置
}

// PrometheusConfig Prometheus监控配置结构体
type PrometheusConfig struct {
	Path string `yaml:"path"` // Prometheus指标暴露路径
	Port int    `yaml:"port"` // Prometheus指标暴露端口
}

// HealthCheckConfig 健康检查配置结构体
type HealthCheckConfig struct {
	Path     string `yaml:"path"`     // 健康检查路径
	Interval int    `yaml:"interval"` // 健康检查间隔（秒）
}

// LoadConfig 加载配置文件
// 按以下顺序加载配置：
// 1. 从命令行参数获取配置文件路径
// 2. 从配置文件加载基础配置
// 3. 从环境变量覆盖敏感信息
// 4. 验证配置有效性
func LoadConfig() (*Config, error) {
	// 定义命令行参数
	configPath := flag.String("c", "./configs", "配置文件所在目录路径")
	configName := flag.String("env", "dev", "配置文件类型，dev/prod/test")
	flag.Parse()

	// 设置配置文件信息
	viper.SetConfigName(*configName + "_config") // 配置文件名（不带扩展名）
	viper.SetConfigType("yaml")                  // 配置文件类型
	viper.AddConfigPath(*configPath)             // 配置文件路径

	// 读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %v", err)
	}

	// 解析配置到结构体
	var config Config
	if err := viper.Unmarshal(&config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %v", err)
	}

	// 从环境变量加载敏感信息
	if dbPassword := os.Getenv("DB_PASSWORD"); dbPassword != "" {
		config.Database.MySQL.Password = dbPassword
		config.Database.PostgreSQL.Password = dbPassword
	}

	if jwtSecret := os.Getenv("JWT_SECRET"); jwtSecret != "" {
		config.Security.JWTSecret = jwtSecret
	}

	// 验证配置
	if err := validateConfig(&config); err != nil {
		return nil, fmt.Errorf("配置验证失败: %v", err)
	}

	return &config, nil
}

// validateConfig 验证配置有效性
// 检查必要的配置项是否存在且有效
func validateConfig(config *Config) error {
	// 验证服务器配置
	if config.Server.Port <= 0 {
		return fmt.Errorf("无效的服务器端口: %d", config.Server.Port)
	}

	// 验证数据库配置
	if config.Database.Type != "mysql" && config.Database.Type != "postgresql" {
		return fmt.Errorf("不支持的数据库类型: %s", config.Database.Type)
	}

	// 验证日志配置
	if config.Log.Level != "debug" && config.Log.Level != "info" &&
		config.Log.Level != "warn" && config.Log.Level != "error" &&
		config.Log.Level != "fatal" {
		return fmt.Errorf("无效的日志级别: %s", config.Log.Level)
	}

	// 验证安全配置
	if config.Security.JWTSecret == "" {
		// 在开发环境下使用默认密钥
		if os.Getenv("GO_ENV") == "dev" || os.Getenv("GO_ENV") == "" {
			config.Security.JWTSecret = "dev-jwt-secret-key"
		} else {
			return fmt.Errorf("JWT密钥不能为空")
		}
	}

	// 验证JWT过期时间，如果未设置则使用默认值24小时
	if config.Security.JWTExpire <= 0 {
		config.Security.JWTExpire = 86400 // 默认24小时（秒）
	}

	return nil
}

// GetMySQLDSN 生成MySQL数据源连接字符串
// 返回格式：username:password@tcp(host:port)/
func (c *MySQLConfig) GetMySQLDSN() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/",
		c.Username, c.Password, c.Host, c.Port)
}

// GetPostgreSQLDSN 生成PostgreSQL数据源连接字符串
// 返回格式：host=localhost port=5432 user=postgres password=secret dbname=mydb sslmode=disable
func (c *PostgreSQLConfig) GetPostgreSQLDSN() string {
	return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
		c.Host, c.Port, c.Username, c.Password, c.DBName, c.SSLMode)
}
